<template>
  <div class="mobile-login">
    <div class="login-container">
      <!-- 登录界面 -->
      <div v-if="!loginSuccess" class="login-section">
        <h2>移动端登录</h2>
        <p class="subtitle">登录后可以扫码确认PC端登录</p>

        <el-form ref="loginFormRef" :model="loginForm" :rules="loginRules" class="login-form">
          <el-form-item prop="userName">
            <el-input v-model="loginForm.userName" placeholder="请输入用户名" prefix-icon="User" />
          </el-form-item>

          <el-form-item prop="password">
            <el-input v-model="loginForm.password" type="password" placeholder="请输入密码" prefix-icon="Lock"
              show-password />
          </el-form-item>

          <el-form-item>
            <el-button type="primary" class="login-btn" :loading="loading" @click="handleLogin">
              登录
            </el-button>
          </el-form-item>
        </el-form>
      </div>

      <!-- 主界面 -->
      <div v-else class="main-section">
        <div class="user-info">
          <div class="avatar">
            <el-icon class="avatar-icon">
              <User />
            </el-icon>
          </div>
          <h3>{{ userInfo.name }}</h3>
          <p class="role">{{ userInfo.role || '用户' }}</p>
        </div>

        <div class="action-buttons">
          <el-button type="primary" class="scan-btn" @click="startCameraScan">
            <el-icon>
              <Camera />
            </el-icon>
            扫码登录PC端
          </el-button>

          <el-button class="logout-btn" @click="logout">
            退出登录
          </el-button>
        </div>

        <div class="tips">
          <h4>使用说明</h4>
          <p>• 点击"扫码登录PC端"按钮</p>
          <p>• 扫描PC端显示的二维码</p>
          <p>• 确认后PC端将自动登录</p>
        </div>
      </div>
    </div>

    <!-- 扫码模态框 -->
    <el-dialog v-model="showScanModal" title="扫码登录" width="90%" :before-close="handleCloseScanModal">
      <div class="scan-container">
        <!-- 摄像头扫码界面 -->
        <div v-if="cameraScanning" class="camera-scanning">
          <div class="camera-container">
<!--            用于显示摄像头画面-->
            <video ref="video" style="display: none"></video>
<!--            用于逐帧绘制视频流并解析二维码-->
            <canvas ref="canvas" class="scan-canvas"></canvas>
<!--            //用于显示二维码-->
            <div class="scan-overlay">
<!--              //绘制二维码边框-->
              <div class="scan-frame"></div>
              <p>将二维码放入框内</p>
            </div>
          </div>

          <el-button type="danger" @click="stopCameraScan">
            停止扫描
          </el-button>
        </div>

        <!-- 扫描结果 -->
        <div v-if="scanResult" class="scan-result">
          <div :class="scanSuccess ? 'success' : 'error'">
            {{ scanResult }}
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import jsQR from 'jsqr'

export default {
  name: 'MobileLogin',
  data() {
    return {
      // 登录相关
      loginSuccess: false,
      loading: false,
      loginForm: {
        userName: '',
        password: ''
      },
      loginRules: {
        userName: [
          { required: true, message: '请输入用户名', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' }
        ]
      },
      userInfo: {},

      // 扫码相关
      showScanModal: false,
      scanResult: '',
      scanSuccess: false,
      cameraScanning: false,
      mediaStream: null,
      animationId: null
    }
  },
  mounted() {
    this.checkLoginStatus()
  },
  beforeUnmount() {
    this.stopCameraScan()
  },
  methods: {
    // 检查登录状态
    checkLoginStatus() {
      const userInfo = localStorage.getItem('userInfo')
      if (userInfo) {
        this.loginSuccess = true
        this.userInfo = JSON.parse(userInfo)
      }
    },

    // 处理登录
    async handleLogin() {
      try {
        await this.$refs.loginFormRef.validate()
        this.loading = true

        const response = await this.$axios.post('/api/user/login', null, {
          params: {
            name: this.loginForm.userName,
            password: this.loginForm.password
          }
        })

        if (response.data.code === '0') {
          // 保存用户信息到localStorage
          this.userInfo = {
            name: this.loginForm.userName,
            role: response.data.data.role
          }
          localStorage.setItem('userInfo', JSON.stringify(this.userInfo))

          this.loginSuccess = true
          this.$message.success('登录成功！')
        } else {
          this.$message.error(response.data.msg || '登录失败')
        }
      } catch (error) {
        console.error('登录失败:', error)
        this.$message.error('登录失败，请重试')
      } finally {
        this.loading = false
      }
    },

    // 退出登录
    logout() {
      localStorage.removeItem('userInfo')
      this.loginSuccess = false
      this.loginForm.userName = ''
      this.loginForm.password = ''
      this.$message.success('已退出登录')
    },

    // 处理扫描结果
    async handleScanResult(qrContent) {
      try {
        // 解析二维码内容，提取token
        const url = new URL(qrContent);
        const token = url.searchParams.get('token');
        if (token) {
          this.scanResult = '正在确认登录...';
          // 调用后端接口确认登录
          const response = await this.$axios.post('/api/qr/confirm-direct', {
            token: token,
            userName: this.userInfo.name
          });
          if (response.data.code === '0') {
            this.scanResult = '登录确认成功！PC端正在登录...';
            this.scanSuccess = true;
          } else {
            this.scanResult = response.data.msg || '确认登录失败';
            this.scanSuccess = false;
          }
        } else {
          this.scanResult = '二维码内容无效，未检测到token参数';
          this.scanSuccess = false;
        }
      } catch (error) {
        console.error('解析二维码或确认登录失败:', error);
        this.scanResult = '二维码内容无效或确认登录失败';
        this.scanSuccess = false;
      }
    },

    // 开始摄像头扫码
    async startCameraScan() {
      try {
        this.showScanModal = true
        this.cameraScanning = true
        this.scanResult = ''
        this.scanSuccess = false

        // 详细的浏览器兼容性检查
        this.scanResult = '正在检查浏览器兼容性...'

        // 检查是否在HTTPS环境下
        if (location.protocol !== 'https:' && location.hostname !== 'localhost' && location.hostname !== '127.0.0.1') {
          throw new Error('摄像头访问需要HTTPS环境，请使用HTTPS协议访问')
        }

        // 检查navigator.mediaDevices支持
        if (!navigator.mediaDevices) {
          throw new Error('浏览器不支持MediaDevices API，请使用现代浏览器')
        }

        // 检查getUserMedia支持
        if (!navigator.mediaDevices.getUserMedia) {
          // 尝试旧版API
          const getUserMedia = navigator.getUserMedia ||
            navigator.webkitGetUserMedia ||
            navigator.mozGetUserMedia ||
            navigator.msGetUserMedia

          if (!getUserMedia) {
            throw new Error('浏览器不支持摄像头访问，请使用Chrome、Firefox、Safari等现代浏览器')
          }

          // 使用旧版API
          this.scanResult = '正在使用兼容模式启动摄像头...'
          this.mediaStream = await new Promise((resolve, reject) => {
            getUserMedia.call(navigator, { video: true }, resolve, reject)
          })
        } else {
          // 使用新版API
          this.scanResult = '正在请求摄像头权限...'

          // 尝试不同的摄像头配置
          const cameraConfigs = [
            { video: { facingMode: 'environment', width: { ideal: 800 }, height: { ideal: 600 } } },
            { video: { facingMode: 'user', width: { ideal: 800 }, height: { ideal: 600 } } },
            { video: { width: { ideal: 800 }, height: { ideal: 600 } } },
            { video: true }
          ]

          let streamObtained = false
          for (const config of cameraConfigs) {
            try {
              this.mediaStream = await navigator.mediaDevices.getUserMedia(config)
              streamObtained = true
              break
            } catch (configError) {
              console.log('摄像头配置失败:', config, configError.name)
              continue
            }
          }

          if (!streamObtained) {
            throw new Error('无法获取摄像头权限，请检查浏览器设置并允许摄像头访问')
          }
        }

        // 设置视频流到video元素
        this.scanResult = '正在初始化视频流...'
        const video = this.$refs.video
        video.srcObject = this.mediaStream

        // 等待视频加载
        await new Promise((resolve, reject) => {
          video.onloadedmetadata = resolve
          video.onerror = reject
          video.play().catch(reject)
        })

        // 开始扫描
        this.scanResult = '正在扫描，请将二维码放入框内...'
        this.tick()

      } catch (error) {
        console.error('启动摄像头扫描失败:', error)

        // 根据错误类型提供具体的解决方案
        let errorMessage = '启动摄像头扫描失败: '

        if (error.name === 'NotAllowedError') {
          errorMessage += '摄像头权限被拒绝，请在浏览器地址栏点击摄像头图标并选择"允许"'
        } else if (error.name === 'NotFoundError') {
          errorMessage += '未找到摄像头设备，请检查设备是否连接摄像头'
        } else if (error.name === 'NotReadableError') {
          errorMessage += '摄像头被其他应用占用，请关闭其他使用摄像头的应用'
        } else if (error.name === 'OverconstrainedError') {
          errorMessage += '摄像头不支持请求的分辨率，正在尝试其他配置...'
          // 可以在这里重试更简单的配置
        } else if (error.message.includes('HTTPS')) {
          errorMessage = error.message
        } else {
          errorMessage += error.message
        }

        this.scanResult = errorMessage
        this.cameraScanning = false
      }
    },

    // 扫描帧处理
    tick() {
      if (!this.cameraScanning) return

      const video = this.$refs.video
      const canvas = this.$refs.canvas
      const ctx = canvas.getContext('2d')

      // 设置canvas尺寸
      canvas.width = 800
      canvas.height = 600

      // 绘制视频帧到canvas
      ctx.drawImage(video, 0, 0, 800, 600)

      // 获取图像数据
      const imageData = ctx.getImageData(0, 0, 800, 600)

      // 使用jsQR解析二维码
      const code = jsQR(imageData.data, imageData.width, imageData.height)

      if (code) {
        console.log('扫描成功:', code.data)
        // 绘制二维码框
        this.drawQRBox(code.location)
        // 处理扫描结果
        this.handleScanResult(code.data)
        // 停止扫描
        this.stopCameraScan()
        return
      }

      // 继续扫描下一帧
      this.animationId = requestAnimationFrame(() => this.tick())
    },

    // 绘制二维码框
    drawQRBox(location) {
      const canvas = this.$refs.canvas
      const ctx = canvas.getContext('2d')

      // 绘制边框
      ctx.beginPath()
      ctx.moveTo(location.topLeftCorner.x, location.topLeftCorner.y)
      ctx.lineTo(location.topRightCorner.x, location.topRightCorner.y)
      ctx.lineTo(location.bottomRightCorner.x, location.bottomRightCorner.y)
      ctx.lineTo(location.bottomLeftCorner.x, location.bottomLeftCorner.y)
      ctx.closePath()

      ctx.strokeStyle = '#00ff00'
      ctx.lineWidth = 3
      ctx.stroke()
    },

    // 停止摄像头扫描
    async stopCameraScan() {
      // 停止动画帧
      if (this.animationId) {
        cancelAnimationFrame(this.animationId)
        this.animationId = null
      }

      // 停止视频流
      if (this.mediaStream) {
        this.mediaStream.getTracks().forEach(track => track.stop())
        this.mediaStream = null
      }

      this.cameraScanning = false
    },

    // 关闭扫码模态框
    handleCloseScanModal() {
      this.stopCameraScan()
      this.showScanModal = false
      this.scanResult = ''
      this.scanSuccess = false
    }
  }
}
</script>

<style scoped>
.mobile-login {
  min-height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.login-container {
  background: white;
  padding: 30px;
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  width: 100%;
  max-width: 400px;
}

.login-section h2 {
  text-align: center;
  color: #333;
  margin-bottom: 10px;
}

.subtitle {
  text-align: center;
  color: #666;
  margin-bottom: 30px;
  font-size: 14px;
}

.login-form {
  margin-bottom: 20px;
}

.login-btn {
  width: 100%;
}

/* 主界面样式 */
.main-section {
  text-align: center;
}

.user-info {
  margin-bottom: 30px;
}

.avatar {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 20px;
}

.avatar-icon {
  font-size: 40px;
  color: white;
}

.user-info h3 {
  color: #333;
  margin-bottom: 5px;
}

.role {
  color: #666;
  font-size: 14px;
}

.action-buttons {
  margin-bottom: 30px;
}

.scan-btn,
.logout-btn {
  width: 100%;
  margin-bottom: 15px;
  height: 50px;
  font-size: 16px;
}

.scan-btn {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
}

.scan-btn:hover {
  background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
}

.tips {
  padding: 20px;
  background: #f8f9fa;
  border-radius: 8px;
  text-align: left;
}

.tips h4 {
  color: #333;
  margin-bottom: 15px;
  text-align: center;
}

.tips p {
  margin: 8px 0;
  color: #666;
  font-size: 14px;
}

/* 扫码模态框样式 */
.scan-container {
  text-align: center;
  padding: 20px 0;
}

/* 摄像头扫码样式 */
.camera-scanning {
  padding: 20px 0;
}

.camera-container {
  position: relative;
  width: 300px;
  height: 300px;
  margin: 0 auto 20px;
  border: 2px solid #ddd;
  border-radius: 8px;
  overflow: hidden;
}

.scan-canvas {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.scan-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.scan-frame {
  width: 200px;
  height: 200px;
  border: 2px solid #409eff;
  border-radius: 8px;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.3);
}

.scan-overlay p {
  margin-top: 20px;
  color: white;
  font-size: 14px;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
}

.scan-result {
  margin-top: 20px;
  padding: 15px;
  border-radius: 6px;
}

.scan-result .success {
  color: #67c23a;
  background: #f0f9ff;
  padding: 10px;
  border-radius: 4px;
}

.scan-result .error {
  color: #f56c6c;
  background: #fef0f0;
  padding: 10px;
  border-radius: 4px;
}
</style>